<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 原型 prototype 函数特有的 为了继承
        // 原型链 _proto_ =>  [[prototype]]
        // 
        // console.log({})

        // 构造函数
        // function Preson(){

        // }

        // Preson.prototype.name = '小米';
        // Preson.prototype.age = 12;
        // Preson.prototype.getAge = function(){
        //     console.log(this.age);
        // }
        // 实例
        // let person = new Preson();
        // person.age = 24;
        // console.log(person.age);
        // person.getAge()
        // 原型链的查找规则 从当前实例属性查找，找到返回 没有就顺着原型链一层一层网上找
        // 就近原则
        // 直到找到null为止 找不到的话会报错 属性undefined 方法报错
        // console.log(person.demo)
        // person.abc()

        // 查找自身的私有属性
        // let item;
        // for(item in person){
        //     if(person.hasOwnProperty(item)){
        //         console.log(item);
        //     }
        // }


        // part 2
        // class Person {
        //     constructor(name){
        //         this.name = name;
        //     }

        //     sayHi(){
        //         console.log('hi')
        //     }
        // }
        // class Student extends Person{
        //     constructor(name,score){
        //         // this.name = name;
        //         super(name);
        //         this.score = score;
        //     }
   
        //     introduce(){
        //         console.log(`${this.name},${this.score}`);
        //     }
        // }

        // const student = new Student('张三',99);
        // console.log(student);
        // student.introduce();
        // student.sayHi();
        // console.log(student.hasOwnProperty('score '))

        // // 隐式原型
        // // console.log(student.__proto__)

        // console.log(Object.__proto__ === Function.prototype)

        // console.log(Function.prototype instanceof Object)
      
        // console.log(Foo.__proto__ === Function.prototype)
        // console.log(Function.__proto__ === Function.prototype)
        // Object.prototype.constructor

        // 1、对象都有__proto__ ，指向构造函数的prototype
        function Foo(){}
        const foo = new Foo()
        console.log(foo.__proto__ === Foo.prototype)
        // 2、构造函数都有prototype属性，是个对象 又叫原型对象 函数也是个对象 函数由Function实例化
        console.log(Foo.__proto__ === Function.prototype)
        // 3、原型对象上的constructor是构造函数
        console.log(foo.__proto__.constructor === Foo)
        console.log(Foo.prototype.constructor === Foo)
        // 4、顶级构造函数为Function 自己由自己构造 其它构造函数由其实例化完成 顶级对象为Object 
        console.log(Function.__proto__ === Function.prototype)
        console.log(Function.prototype.__proto__ === Object.prototype)
        console.log(Foo.prototype.__proto__ === Object.prototype)

        console.log(Object.prototype.__proto__ === null)
        // Object.prototype.__proto__ === Object.prototype 为了避免死循环
        // console.log(Object.prototype)
        // 自定义对象 与 内置对象？
        // 原型链作用
        // 1、数据共享节省内存空间
        // 2、为了实现继承

        // 原型链的应用
</script>
</body>
</html>